package com.zhouyu.mysql;

import com.zhouyu.mysql.core.DTuple;
import com.zhouyu.mysql.core.DTupleUtil;
import com.zhouyu.mysql.dict.DictTable;
import com.zhouyu.mysql.dict.SystemDict;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.select.FromItemVisitorAdapter;
import net.sf.jsqlparser.statement.select.PlainSelect;

/**
 * 大都督周瑜（我的微信: dadudu6789）
 */
public class SqlOptimizer {

    public QEP_TAB optimize(PlainSelect plainSelect) {
        return new QEP_TAB(plainSelect);
    }

    // 里面其实有一个QEP_TAB属性，表示查询执行计划表，也就是执行计划
    static class QEP_TAB {

        private final SqlExecutor sqlExecutor = new SqlExecutor();

        private PlainSelect plainSelectStatement;

        public QEP_TAB(PlainSelect plainSelectStatement) {
            this.plainSelectStatement = plainSelectStatement;
        }

        public String exec() {

            // 获取表名
            final String[] tableNameArray = new String[1];
            plainSelectStatement.getFromItem().accept(new FromItemVisitorAdapter() {
                @Override
                public void visit(Table table) {
                    tableNameArray[0] = table.getName();
                }
            });
            String tableName = tableNameArray[0];
            DictTable dictTable = SystemDict.getInstance().getNameTables().get(tableName);

            DTuple dTuple = DTupleUtil.convert(plainSelectStatement);

            if (!dTuple.getFields().isEmpty()) {

                int rootPageNo = 0;
                boolean isSecondary = false;

                // where条件后面是id，则走主键索引，否则走a字段辅助索引
                if ("id".equals(dTuple.getFields().get(0).getDictColumn().getName())) {
                    rootPageNo = dictTable.getPageNo();
                } else if ("a".equals(dTuple.getFields().get(0).getDictColumn().getName())) {
                    // 这里应该要判断where条件后面的字段，看能走哪些索引，并最终选择出一个索引，我们写死
                    isSecondary = true;
                    rootPageNo = SystemDict.getInstance().getTableIdIndexes().get(dictTable.getTableId()).get(0).getPageNo();
                }

                return sqlExecutor.select(plainSelectStatement, false, isSecondary, rootPageNo);
            } else {
                // 走全表扫描
                return sqlExecutor.select(plainSelectStatement, true, false, dictTable.getPageNo());
            }


        }
    }


}
